import 'package:flutter/material.dart';
import 'package:petitparser/petitparser.dart';

///petitparser 支持错误恢复和错误报告。
///可以使用 FailureParser 来创建一个总是失败的解析器，或者使用 or 方法来处理解析失败的情况。
class EErrorParser extends StatefulWidget {
  const EErrorParser({super.key});

  @override
  State<EErrorParser> createState() => _EErrorParserState();
}

class _EErrorParserState extends State<EErrorParser> {
  var resultStr = '';
  final invalidStr = 'Invalid input';
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('错误处理'),
        ),
        body: SingleChildScrollView(
          child: Container(
            padding: EdgeInsets.all(16),
            child: Column(
              children: [
                Text('待解析数据:"1 +a"'),
                SizedBox(height: 10),
                TextButton(
                    onPressed: () {
                      _buildParser();
                      setState(() {});
                    },
                    child: Text('开始解析')),
                Text('解析结果："'),
                SizedBox(height: 10),
                Container(
                  color: const Color.fromARGB(255, 224, 224, 224),
                  child: Text(resultStr),
                ),
              ],
            ),
          ),
        ));
  }

  void _buildParser() {
    // 创建一个解析器，用于解析一个数字字符并将其转换为整数
    final digitParser = digit().flatten().map(int.parse);

    // 创建一个解析器，用于解析 '+' 字符并忽略其两边的空白字符
    final operatorParser = char('+').trim();

    // 使用 `seq` 方法将 `digitParser` 和 `operatorParser` 组合成一个解析器
    // 这个解析器可以解析形如 "[数字] + [数字]" 的字符串
    final expressionParser = digitParser.seq(operatorParser).seq(digitParser);

    // 创建一个总是失败的解析器，当解析失败时，它将返回一个错误消息
    final failureParser = failure('解析出错：Invalid input');

    // 使用 `or` 方法将 `expressionParser` 和 `failureParser` 组合成一个新的解析器
    // 这个新的解析器在 `expressionParser` 解析失败时，会尝试使用 `failureParser` 进行解析
    final parser = expressionParser.or(failureParser);

    // 使用新的解析器来解析字符串 '1 + a'
    // 这个字符串是无效的，因为它包含一个非数字字符 'a'
    final result = parser.parse('1 + a');
    if (result.isFailure) {
      resultStr = result.message;
      // 如果解析失败，打印出错误消息
      print(result.message);
    } else {
      // 如果解析成功，打印出两个数字的和
      final values = result.value;
      final firstNumber = values[0];
      final secondNumber = values[2];
      resultStr = '$firstNumber\n\n$secondNumber';
      print('The sum is ${firstNumber + secondNumber}');
    }
  }
}
